﻿#pragma once

#define MAX_USER_COUNT 50           // 最大用户数
#define MAX_USERNAME_LEN 16         // 最大用户名长度
#define SERVER_IP "192.168.1.112"   // 服务器 IP 地址
#define SERVER_PORT 10000           // 服务器端口号

#define USERNAME_BUF_LEN (MAX_USERNAME_LEN + 1) // 用户名缓存长度

// 游戏结束原因
typedef enum GameOverReason {
    LOST,           // 失败
    SELF_ADMIT,     // 自己认输
    RIVAL_ADMIT,    // 对手认输
    WON             // 胜利
} GameOverReason;

// 协议类型
typedef enum ProtocolType {
    FIND_USERS,     // 寻找其它用户
    GAME_OVER,      // 游戏结束
    INVITE_REQUEST, // 挑战请求
    INVITE_RESULT,  // 挑战结果
    LOGON,          // 登录
    PUT_PIECE,      // 放置棋子
    QUIT_GAME       // 退出游戏
} ProtocolType;

// 协议
typedef struct GomokuProtocol {
    ProtocolType mType;                 // 类型
    TCHAR mUsername[USERNAME_BUF_LEN];  // 用户名
} GomokuProtocol;
GomokuProtocol* New_GomokuProtocol(ProtocolType, LPCTSTR);

// 寻找用户结果
typedef struct FindUsersResult {
    ProtocolType mType;                                     // 协议类型
    TCHAR mUsernameList[MAX_USER_COUNT][USERNAME_BUF_LEN];  // 用户名列表
} FindUsersResult;
FindUsersResult* New_FindUsersResult();

// 游戏结束
typedef struct GameOver {
    ProtocolType mType;                 // 协议类型
    TCHAR mRivalName[USERNAME_BUF_LEN]; // 对手的名字
    GameOverReason mReason;             // 结束原因
} GameOver;
GameOver* New_GameOver(GameOverReason, LPCTSTR);

// 挑战请求
typedef struct InviteRequest {
    ProtocolType mType;                 // 协议类型
    TCHAR mUsername[USERNAME_BUF_LEN];  // 用户名
    TCHAR mRivalName[USERNAME_BUF_LEN]; // 对手的名字
} InviteRequest;
InviteRequest* New_InviteRequest(LPCTSTR, LPCTSTR);

// 挑战结果
typedef struct InviteResult {
    ProtocolType mType;                 // 协议类型
    TCHAR mUsername[USERNAME_BUF_LEN];  // 用户名
    BOOL mAccept;                       // 接受挑战则为 TRUE，否则为 FALSE
    TCHAR mRivalName[USERNAME_BUF_LEN]; // 对手的名字
} InviteResult;
InviteResult* New_InviteResult(BOOL, LPCTSTR, LPCTSTR);

// 放置棋子
typedef struct PutPiece {
    ProtocolType mType;                 // 协议类型
    TCHAR mRivalName[USERNAME_BUF_LEN]; // 对手的名字
    int mX;                             // x 坐标（窗口坐标）
    int mY;                             // y 坐标（窗口坐标）
} PutPiece;
PutPiece* New_PutPiece(LPCTSTR, int, int);
